home *** CD-ROM | disk | FTP | other *** search
- /*----------------------------------------------------------------------
- Routines used to hand off messages to local agents for sending/posting
-
- The two exported routines are:
-
- 1) smtp_command() -- used to get local transport agent to invoke
- 2) post_handoff() -- used to pass messages to local posting agent
-
- ----*/
-
-
-
- /*
- * Protos for "sendmail" internal functions
- */
- static char *mta_parse_post PROTO((METAENV *, BODY *, char *, char *));
- static long pine_pipe_soutr_nl PROTO((void *, char *));
-
-
-
- /* ----------------------------------------------------------------------
- Figure out command to start local SMTP agent
-
- Args: errbuf -- buffer for reporting errors (assumed non-NULL)
-
- Returns an alloc'd copy of the local SMTP agent invocation or NULL
-
- ----*/
- char *
- smtp_command(errbuf)
- char *errbuf;
- {
- #if defined(SENDMAIL) && defined(SENDMAILFLAGS)
- char tmp[256];
-
- sprintf(tmp, "%s %s", SENDMAIL, SENDMAILFLAGS);
- return(cpystr(tmp));
- #else
- strcpy(errbuf, "No default posting command.");
- return(NULL);
- #endif
- }
-
-
-
- /*----------------------------------------------------------------------
- Hand off given message to local posting agent
-
- Args: envelope -- The envelope for the BCC and debugging
- header -- The text of the message header
- errbuf -- buffer for reporting errors (assumed non-NULL)
-
- ----*/
- int
- mta_handoff(header, body, errbuf)
- METAENV *header;
- BODY *body;
- char *errbuf;
- {
- char cmd_buf[256], *cmd = NULL;
-
- /*
- * A bit of complicated policy implemented here.
- * There are two posting variables sendmail-path and smtp-server.
- * Precedence is in that order.
- * They can be set one of 4 ways: fixed, command-line, user, or globally.
- * Precedence is in that order.
- * Said differently, the order goes something like what's below.
- *
- * NOTE: the fixed/command-line/user precendence handling is also
- * indicated by what's pointed to by ps_global->VAR_*, but since
- * that also includes the global defaults, it's not sufficient.
- */
-
- if(ps_global->FIX_SENDMAIL_PATH
- && ps_global->FIX_SENDMAIL_PATH[0]){
- cmd = ps_global->FIX_SENDMAIL_PATH;
- }
- else if(!(ps_global->FIX_SMTP_SERVER
- && ps_global->FIX_SMTP_SERVER[0])){
- if(ps_global->COM_SENDMAIL_PATH
- && ps_global->COM_SENDMAIL_PATH[0]){
- cmd = ps_global->COM_SENDMAIL_PATH;
- }
- else if(!(ps_global->COM_SMTP_SERVER
- && ps_global->COM_SMTP_SERVER[0])){
- if(ps_global->USR_SENDMAIL_PATH
- && ps_global->USR_SENDMAIL_PATH[0]){
- cmd = ps_global->USR_SENDMAIL_PATH;
- }
- else if(!(ps_global->USR_SMTP_SERVER
- && ps_global->USR_SMTP_SERVER[0])){
- if(ps_global->GLO_SENDMAIL_PATH
- && ps_global->GLO_SENDMAIL_PATH[0]){
- cmd = ps_global->GLO_SENDMAIL_PATH;
- }
- #ifdef DF_SENDMAIL_PATH
- /*
- * This defines the default method of posting. So,
- * unless we're told otherwise use it...
- */
- else if(!(ps_global->GLO_SMTP_SERVER
- && ps_global->GLO_SMTP_SERVER[0])){
- strcpy(cmd = cmd_buf, DF_SENDMAIL_PATH);
- }
- #endif
- }
- }
- }
-
- *errbuf = '\0';
- if(cmd){
- dprint(4, (debugfile, "call_mailer via cmd: %s\n", cmd));
-
- (void) mta_parse_post(header, body, cmd, errbuf);
- return(1);
- }
- else
- return(0);
- }
-
-
-
- /*----------------------------------------------------------------------
- Hand off given message to local posting agent
-
- Args: envelope -- The envelope for the BCC and debugging
- header -- The text of the message header
- errbuf -- buffer for reporting errors (assumed non-NULL)
-
- Fork off mailer process and pipe the message into it
- Called to post news via Inews when NNTP is unavailable
-
- ----*/
- char *
- post_handoff(header, body, errbuf)
- METAENV *header;
- BODY *body;
- char *errbuf;
- {
- char *err = NULL;
- #ifdef SENDNEWS
- char *s;
-
- if(s = strstr(header->env->date," (")) /* fix the date format for news */
- *s = '\0';
-
- if(err = mta_parse_post(header, body, SENDNEWS, errbuf))
- sprintf(err = errbuf, "News not posted: \"%s\": %s", SENDNEWS, err);
-
- if(s)
- *s = ' '; /* restore the date */
-
- #else /* !SENDNEWS */ /* this is the default case */
- sprintf(err = errbuf, "Can't post, NNTP-server must be defined!");
- #endif /* !SENDNEWS */
- return(err);
- }
-
-
-
- /*----------------------------------------------------------------------
- Hand off message to local MTA; it parses recipients from 822 header
-
- Args: header -- struct containing header data
- body -- struct containing message body data
- cmd -- command to use for handoff (%s says where file should go)
- errs -- pointer to buf to hold errors
-
- ----*/
- static char *
- mta_parse_post(header, body, cmd, errs)
- METAENV *header;
- BODY *body;
- char *cmd;
- char *errs;
- {
- char c, *p, *result = NULL;
- int rv;
- PIPE_S *pipe;
-
- dprint(1, (debugfile, "=== mta_parse_post(%s) ===\n", cmd));
-
- /* tie off cmd */
- for(p = cmd; (c = *p) && !isspace(*p); p++)
- ;
-
- *p = *errs = '\0';
- rv = can_access(cmd, EXECUTE_ACCESS);
- *p = c;
- if(!rv){
- if(pipe = open_system_pipe(cmd, &result, NULL,
- PIPE_STDERR | PIPE_WRITE | PIPE_PROT | PIPE_NOSHELL)){
- if(!pine_rfc822_output(header, body, pine_pipe_soutr_nl,
- (TCPSTREAM *) pipe))
- strcpy(errs, "Error posting.");
-
- if(close_system_pipe(&pipe) && !*errs){
- sprintf(errs, "Posting program %s returned error", cmd);
- if(result)
- display_output_file(result, "POSTING ERRORS", errs);
- }
- }
- else
- sprintf(errs, "Error running cmd: %s", cmd);
-
- if(result){
- unlink(result);
- fs_give((void **)&result);
- }
- }
- else
- sprintf(errs, "Error with \"%s\" : %s", cmd,
- (errno > 0) ? error_description(errno) : "not executable");
-
- return(*errs ? errs : NULL);
- }
-
-
- /*
- * pine_pipe_soutr - Replacement for tcp_soutr that writes one of our
- * pipes rather than a tcp stream
- */
- static long
- pine_pipe_soutr_nl (stream,s)
- void *stream;
- char *s;
- {
- long rv = T;
- char *p;
- size_t n;
-
- while(*s && rv){
- /* map CR LF ? */
- if(n = (p = strstr(s, "\015\012")) ? p - s : strlen(s))
- do
- rv = fwrite(s, n, (size_t) 1, ((PIPE_S *)stream)->ofilep);
- while(!rv && ferror(((PIPE_S *)stream)->ofilep) && errno == EINTR);
-
- if(p && rv){
- s = p + 2;
- do /* write UNIX EOL */
- rv = fwrite("\n", (size_t)1, (size_t)1,
- ((PIPE_S *)stream)->ofilep);
- while(!rv && ferror(((PIPE_S *)stream)->ofilep)
- && errno == EINTR);
- }
- else
- break;
- }
-
- return(rv);
- }
-